#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
可变参数泛型配置测试

测试 SymbolRegistry 的泛型类型处理功能
"""

from mcpy.symbol_registry import get_global_registry
from mcpy.symbol_meta import TypeInfo, TypeKind


class TestVariadicGenerics:
    """可变参数泛型配置测试类"""

    def setup_method(self):
        """测试方法初始化"""
        self.registry = get_global_registry()

    def test_tuple_variadic_support(self):
        """测试tuple的可变参数支持"""
        # 测试单参数tuple
        args1 = [TypeInfo(TypeKind.PRIMITIVE, "int")]
        symbol1 = self.registry.lookup_type_symbol("tuple", args1)
        assert symbol1 is not None, "tuple[int]应该能找到对应符号"

        # 测试双参数tuple
        args2 = [
            TypeInfo(TypeKind.PRIMITIVE, "int"),
            TypeInfo(TypeKind.PRIMITIVE, "str"),
        ]
        symbol2 = self.registry.lookup_type_symbol("tuple", args2)
        assert symbol2 is not None, "tuple[int, str]应该能找到对应符号"

        # 测试三参数tuple
        args3 = [
            TypeInfo(TypeKind.PRIMITIVE, "int"),
            TypeInfo(TypeKind.PRIMITIVE, "str"),
            TypeInfo(TypeKind.PRIMITIVE, "bool"),
        ]
        symbol3 = self.registry.lookup_type_symbol("tuple", args3)
        assert symbol3 is not None, "tuple[int, str, bool]应该能找到对应符号"

    def test_tuple_cpp_type_generation(self):
        """测试tuple的C++类型生成"""
        # 测试不同参数数量的C++类型生成
        test_cases = [
            ([TypeInfo(TypeKind.PRIMITIVE, "int")], "std::tuple<int>"),
            (
                [
                    TypeInfo(TypeKind.PRIMITIVE, "int"),
                    TypeInfo(TypeKind.PRIMITIVE, "str"),
                ],
                "std::tuple<int, std::string>",
            ),
            (
                [
                    TypeInfo(TypeKind.PRIMITIVE, "int"),
                    TypeInfo(TypeKind.PRIMITIVE, "str"),
                    TypeInfo(TypeKind.PRIMITIVE, "bool"),
                ],
                "std::tuple<int, std::string, bool>",
            ),
        ]

        for type_args, expected_cpp_type in test_cases:
            symbol = self.registry.lookup_type_symbol("tuple", type_args)
            assert (
                symbol is not None
            ), f"应该能找到tuple符号: {[arg.name for arg in type_args]}"

            if symbol.type_config:
                cpp_type = symbol.type_config.get("cpp_type")
                assert (
                    cpp_type == expected_cpp_type
                ), f"类型参数{[arg.name for arg in type_args]}的C++类型生成错误: 期望{expected_cpp_type}, 实际{cpp_type}"

    def test_fixed_parameter_types(self):
        """测试固定参数类型"""
        # 测试list（固定单参数）
        args_list_valid = [TypeInfo(TypeKind.PRIMITIVE, "int")]
        symbol_list = self.registry.lookup_type_symbol("list", args_list_valid)
        assert symbol_list is not None, "list[int]应该能找到对应符号"

        # 测试dict（固定双参数）
        args_dict_valid = [
            TypeInfo(TypeKind.PRIMITIVE, "str"),
            TypeInfo(TypeKind.PRIMITIVE, "int"),
        ]
        symbol_dict = self.registry.lookup_type_symbol("dict", args_dict_valid)
        assert symbol_dict is not None, "dict[str, int]应该能找到对应符号"

    def test_cpp_type_generation(self):
        """测试C++类型生成"""
        # 测试基本类型
        test_cases = [
            ("list", [TypeInfo(TypeKind.PRIMITIVE, "int")], "mc::array<int>"),
            (
                "dict",
                [
                    TypeInfo(TypeKind.PRIMITIVE, "str"),
                    TypeInfo(TypeKind.PRIMITIVE, "int"),
                ],
                "mc::dict",
            ),
            ("set", [TypeInfo(TypeKind.PRIMITIVE, "int")], "mcpy::variant_set"),
        ]

        for base_type, args, expected_cpp_type in test_cases:
            symbol = self.registry.lookup_type_symbol(base_type, args)
            assert symbol is not None, f"应该能找到{base_type}符号"

            if symbol.type_config:
                cpp_type = symbol.type_config.get("cpp_type")
                assert (
                    cpp_type == expected_cpp_type
                ), f"{base_type}的C++类型生成错误: 期望{expected_cpp_type}, 实际{cpp_type}"

    def test_type_alias_resolution(self):
        """测试类型别名解析"""
        # 测试 List -> list 别名
        args = [TypeInfo(TypeKind.PRIMITIVE, "int")]

        # 直接查找 list
        list_symbol = self.registry.lookup_type_symbol("list", args)

        # 通过别名查找 List
        List_symbol = self.registry.lookup_type_symbol("List", args)

        # 两者应该解析到相同的类型
        if list_symbol and List_symbol:
            assert (
                list_symbol.type_config == List_symbol.type_config
            ), "List和list应该解析到相同的配置"

    def test_edge_cases(self):
        """测试边界情况"""
        # 测试不存在的泛型类型
        args = [TypeInfo(TypeKind.PRIMITIVE, "int")]
        symbol = self.registry.lookup_type_symbol("nonexistent", args)
        assert symbol is None, "不存在的泛型类型应该返回None"

        # 测试空参数 - list 本身是有效类型，应该返回基础模板
        symbol_empty = self.registry.lookup_type_symbol("list", [])
        assert symbol_empty is not None, "list 基础类型应该存在"
